package com.qf.index;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.json.JSONUtil;

import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ReadWp {

    public static void main(String[] args) throws SQLException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(format.format(new Date()) + " 程序开始了~~~");

        int onePageNum = 1000;
//        String limit = "";
        String limit = " limit 1";

        String newDataName = "scholar_25_01.";
        String summaryTable = newDataName + "pm_ut_aid_info_0120";
        String spiderCnCoreTable = newDataName + "spider_cn_core";
        String spiderCnKiAnalysisTable = newDataName + "spider_cnki_analysis";
        String spiderCqVipAnalysisTable = newDataName + "spider_cqvip_analysis";
        String spiderWanFangAnalysisTable = newDataName + "spider_wanfang_analysis";
        String spiderYiiGleAnalysisTable = newDataName + "spider_yiigle_analysis";
        String pmArticleTable = newDataName + "spider_pubmed_vip_extend";
        String utArticleTable = newDataName + "spider_tb_true_92007022_1125";
        String jourMergeTable = newDataName + "basic_jour_merge";
        String quotaTable = newDataName + "basic_core_paper_quota";
        String basicCoreTable = newDataName + "basic_core_paper";
        String wordAndCodeSetMapTable = newDataName + "word_and_code_set_map";
        String fullAbbrKeyWordTable = newDataName + "full_abbr_key_word_1218";
        String pmOrUtIdTablePm = newDataName + "pm_ut_aid_info_pm";
        Map<Integer, Map<Integer, String>> typeIdUrlMap = new ConcurrentHashMap<>();

        // 词（药物，数字代号：1; 基因，数字代号：2; 通路，数字代号：3; 疾病，数字代号：4）和code（1，2，3，4）代码集合。
        Map<String, Set<Integer>> wordAndCodeSetMap = Drug.getWordAndCodeSetMap(wordAndCodeSetMapTable, "id", "word`,`code_set", limit);

        String field = "enkeyword`,`entitle`,`enabs`,`cnau`,`enau`,`vol`,`cnfrom`,`enfrom`,`origin`,`cnfund`,`cntitle`,`cnabs`,`classinfo`,`cnkeyword`,`aurl";
        readWp(spiderCqVipAnalysisTable, onePageNum, limit, "id", field, summaryTable, wordAndCodeSetMap);


        // main
    }


    public static void readWp(String spiderCqVipAnalysisTable, int onePageNum, String limit, String autoId, String field, String summaryTable, Map<String, Set<Integer>> wordAndCodeSetMap) throws SQLException {
        Map<Integer, Integer> dataIdAndAidMap = ReadPm.getDataIdAndAidMap(summaryTable, "id", "weipu_id");
        System.out.println("dataIdAndAidMap.size(): " + dataIdAndAidMap.size());
        int tableMax = Db.use().queryNumber("select max(" + autoId + ") from " + spiderCqVipAnalysisTable).intValue();
        List<String> supportedList = rSet.getSupportedList();
        if (tableMax < 1) {
            return;
        }
        Collection<Integer> tableList = new ArrayList<>();
        NumberUtil.appendRange(0, tableMax + onePageNum, onePageNum, tableList);
        tableList.parallelStream().forEach(startId -> {
            try {
                List<Entity> tableData = Db.use().query("select `" + autoId + "`,`" + field + "` from " + spiderCqVipAnalysisTable + " where " + autoId + " between " + startId + " and " + (startId + onePageNum - 1) + limit);
                for (Entity entry : tableData) {
                    Integer dataId = entry.getInt(autoId);
                    if (!dataIdAndAidMap.containsKey(dataId)) {
                        continue;
                    }
                    String keyword = Utils.getStrField(entry, "enkeyword");
                    String title = Utils.getStrField(entry, "entitle");
                    title = title.startsWith("#_#") ? title.substring("#_#".length()).trim() : title.trim();
                    String abText = Utils.getStrField(entry, "enabs");
                    String cnAuth = Utils.getStrField(entry, "cnau");
                    Set<String> mailSet = new HashSet<>();
                    String di = getMailDoi(abText + " " + cnAuth + " " + Utils.getStrField(entry, "enau"), mailSet);
                    String py = "";
                    String vol = Utils.getStrField(entry, "vol");
                    String cnFrom = Utils.getStrField(entry, "cnfrom");
                    String journal = cnFrom.length() < 4 ? Utils.getStrField(entry, "enfrom") : cnFrom;
                    journal = journal.startsWith("《") && journal.endsWith("》") ? journal.substring("《".length(), journal.length() - "》".length()).trim() : journal;
                    String info = "";
                    if (vol.length() > 4) {
                        String pattern = "(\\d+)年第(\\d+)期(.*)共(\\d+)页";
                        Matcher m = Pattern.compile(pattern).matcher(vol.replace(" ", ""));
                        if (m.find()) {
                            py = m.group(1);
                            String i = m.group(2);
                            String p = m.group(3);
                            info = journal + ". " + (null == py ? "" : py + ";") + (null == i ? "" : (i.startsWith("0") ? i.substring(1) : i) + ":") + (null == p ? ". " : (p.endsWith(",") ? p.substring(0, p.length() - ",".length()) : p) + ". ") + (di.length() > 6 ? ("doi: " + di + ". ") : "");
                        }
                    }
                    int year = (null != py && py.trim().length() == 4 && NumberUtil.isInteger(py.trim())) ? Integer.parseInt(py.trim()) : 1900;
                    List<En.C1Auth> c1List = Utils.getWpC1List(Utils.getStrField(entry, "origin"));
                    List<String> fundList = ReadCd.getCsCdFundList(Utils.getStrField(entry, "cnfund"), supportedList);
                    String cnTi = Utils.getStrField(entry, "cntitle").replaceAll("<[a-z]+ [^>]*>", " ").replaceAll("</[a-z]+>", " ").replaceAll(" +", " ").trim();
                    String cnAb = Utils.getStrField(entry, "cnabs").replaceAll("<[a-z]+ [^>]*>", " ").replaceAll("</[a-z]+>", " ").replaceAll(" +", " ").trim();
                    List<En.CategoryAndInfo> categoryAndInfoList = Drug.getDrug(title, keyword, abText, wordAndCodeSetMap);
                    Matcher matcher = Pattern.compile("\\[([^\\[\\]]+)]").matcher(Utils.getStrField(entry, "classinfo"));
                    Set<String> subjectSet = new HashSet<>();
                    while (matcher.find()) {
                        subjectSet.add(matcher.group(1));
                    }
                    try {
                        Db.use().update(
                                Entity.create().set("doi", di).set("ab", abText).set("doi", di).set("keyword", ReadUt.strToJson(keyword)).set("title", title).set("journal", journal).set("year", year).set("c1_au", JSONUtil.toJsonStr(c1List))
                                        .set("auth", ReadUt.strToJson(cnAuth)).set("drug_gene_pathway_disease", JSONUtil.toJsonStr(categoryAndInfoList)).set("fund_list", JSONUtil.toJsonStr(fundList)).set("info", Fusion.reInfo(info))
                                        .set("cn_ti", cnTi).set("cn_ab", cnAb).set("subject", JSONUtil.toJsonStr(subjectSet)).set("cn_kw", ReadUt.strToJson(entry.getStr("cnkeyword"))).set("mail_list", JSONUtil.toJsonStr(mailSet)),
                                Entity.create(summaryTable).set("id", dataIdAndAidMap.get(dataId)));
                    } catch (SQLException ee) {
                        ee.printStackTrace();
                    }
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        });
        dataIdAndAidMap.clear();
    }

    // 万方，维普等中文数据库中的邮箱提取比较麻烦，单独写了一个。
    public static String getMailDoi(String s, Set<String> mailSet) {
        String di = "";
        if (null != s && (s.contains("＠") || s.contains("@")) && !s.contains("投稿") && !s.contains("征稿") && !s.contains("编辑部") && !s.contains("欢迎作者") && !s.contains("会议") && !s.contains("邮编") && !s.contains("联系人")) {
            // .replaceAll("@([a-zA-Z0-9]+) ([a-zA-Z0-9]+)\\.", "@$1$2.") 处理类似这样的：zyfzf@1 63.net   Pattern.compile("@[a-zA-Z0-9]").matcher(mail).find()，这个功能是排除@后面有中文或其它符号的。
            String[] split = s.toLowerCase().replace("＠", "@").replace("﹕", ":").replace("：", ":").replace("︰", ":").replace("﹒", ".")
                    .replace("．", ".").replace("｡", ".").replace("‧", ".").replace("⋅", ".").replace("。", ".").replace("·", ".").replace("•", ".")
                    .replace("∙", ".").replace("·", "⬢").replace("ㆍ", ".").replace("▪", ".").replace("・", ".").replace("；", " ").replace("，", " ")
                    .replace("？", " ").replace("）", " ").replace("】", " ").replace("！", " ").replace("（", " ").replace("【", " ").replace(";", " ")
                    .replace(",", " ").replace("?", " ").replace(")", " ").replace("]", " ").replace("!", " ").replace("(", " ").replace("[", " ")
                    .replaceAll(" +", " ").replace(" @", "@").replace("@ ", "@").replace(" .", ".").replace(". ", ".").replaceAll(" +", " ")
                    .replace("doi: ", "doi:").replace("doi :", "doi:").replaceAll("@([a-zA-Z0-9]+) ([a-zA-Z0-9]+)\\.", "@$1$2.").split(" ");
            for (String t : split) {
                if (Pattern.compile("@[a-zA-Z0-9]").matcher(t).find() && Utils.fuHeiMail(t)) {
                    mailSet.add(Utils.dellEnd(t));
                }
                if (t.contains("doi:10.")) {
                    String doi = t.substring(t.indexOf("doi:10.") + "doi:".length());
                    if (doi.length() > 11) {
                        di = Utils.dellEnd(doi);
                    }
                }
            }
        }
        return di;
    }


//    public static List<En.FundInfo> getCsCdFundList(String fus, List<String> supportedList, Map<String, Integer> wosFundAndSumMap) {
//        // 实体类FundInfo包含三个属性，如果基金项目不含编号（number），则只有原始信息（info），此时可以把原始信息当作基金信息，这样可以节约占用空间。
//        List<En.FundInfo> fundInfoList = new ArrayList<>();
//        fus = null == fus ? "" : fus;
//        fus = fus.replace(";;-;", "; ");
//        String[] fuSplit = fus.split("; ");
//        for (String original : fuSplit) {
//            String fu = original.replace("－", "-").replace(";-;", " ").replaceAll(" +", " ").replace("（", "(").replace("）", ")").replace("( ", "(")
//                    .replace(" )", ")").replace(" (", "(").replace(") ", ")").replace("，", ",").replace("：", ":").replace(": ", ":").replace(" :", ":")
//                    .replace("- ", "-").replace(" -", "-").replace("；", ";").replace("; ", ";").replace(" ;", ";").replace("＆", "&").replace(", ", "Łł").trim();
//            for (String supported : supportedList) {
//                fu = fu.toLowerCase().startsWith(supported + " by ") ? fu.substring((supported + " by ").length()).trim() : fu;
//            }
//            fu = fu.toLowerCase().startsWith("the ") ? fu.substring("the ".length()) : fu;
//            fu = fu.endsWith("。") ? fu.substring(0, fu.length() - "。".length()) : fu;
//            fu = fu.endsWith(".") ? fu.substring(0, fu.length() - ".".length()) : fu;
//            fu = fu.replaceAll("(\\([0-9A-Za-z-:,. 、;＋/&Łł计划编准号合项批为和同目\\[\\]]{6,36}\\))", "ĺļ$1");
//            fu = fu.replace("Łł", ", ");
//            En.FundInfo fundInfo = new En.FundInfo();
//            fundInfo.setInfo(original);
//            if (fu.contains("ĺļ")) {
//                String fund = fu.substring(0, fu.indexOf("ĺļ"));
//                String number = fu.substring(fu.indexOf("ĺļ") + "ĺļ".length());
//                number = (number.contains(")")) ? number.substring(0, number.indexOf(")") + ")".length()) : number;
//                if (number.toLowerCase().contains("973 program") || number.toLowerCase().contains("863 program")) {
//                    fundInfo.setFund(fund + number);
//                    wosFundAndSumMap.compute(fund + number, (key, value) -> value != null ? (value + 1) : 1);
//                } else {
//                    fundInfo.setNumber(number);
//                    fundInfo.setFund(fund);
//                    wosFundAndSumMap.compute(fund, (key, value) -> value != null ? (value + 1) : 1);
//                }
//            }
//            fundInfoList.add(fundInfo);
//        }
//        return fundInfoList;
//    }

    /*
      CREATE TABLE `pm_ut_aid_info_wp` (
        `id` int(10) NOT NULL AUTO_INCREMENT,
        `key_word_list` longtext COMMENT '关键词集合，此是基于标题、摘要、关键词三处的整合',
        `pm_ut_doi_list` text COMMENT 'pm、doi、ut三者的集合，用于童工的ES检索',
        `journal` text COMMENT '期刊的名称',
        `aid` int(9) DEFAULT NULL COMMENT '因与原表字段重名，pid改为aid，论文的唯一主键，使用老鲍的论文基础表中的自增主键',
        `citation_quota` double DEFAULT NULL COMMENT '引文的质量（按中科院分区表）',
        `reference_quota` double DEFAULT NULL COMMENT '参文的质量',
        `ti_key` text COMMENT '从标题中提取的关键词',
        `ab_key` longtext COMMENT '从摘要中提取的关键词',
        `kw_key` longtext COMMENT '从关键词中提取的关键词(若是主题词给予转换)',
        `abb_word` longtext COMMENT '从简写中提取出来的关键词（是一对）',
        `zky_dalei` int(1) DEFAULT NULL COMMENT '中科院的期刊分区表最佳的大类',
        `jcr_if` double DEFAULT NULL COMMENT 'jcr(scie)期刊影响因子',
        `year` int(4) DEFAULT NULL COMMENT '论文的出版年',
        `title` text COMMENT '论文的原始标题',
        `keyword` longtext COMMENT '论文的原始关键词',
        `ab` longtext COMMENT '论文的原始摘要',
        `mesh` text COMMENT 'PubMed的主题词表，含主题词和副主题词',
        `jid` int(9) DEFAULT NULL COMMENT '期刊的唯一id号，此为期刊关联表的自增主键',
        `discussion` longtext COMMENT '摘要提取出来的特定字段',
        `results` longtext COMMENT '摘要提取出来的特定字段',
        `methods` longtext COMMENT '摘要提取出来的特定字段',
        `background` longtext COMMENT '摘要提取出来的特定字段',
        `c1_list` longtext COMMENT 'wos表中的c1或PubMed表中的作者单位信息字段，只保留单位信息',
        `c1_unit_list` longtext COMMENT '从c1中提取出来的单位信息',
        `rp_list` longtext COMMENT 'wos表中的rp字段，只保留单位信息',
        `rp_unit_list` longtext COMMENT '从rp中提取出来的单位信息',
        `cite` longtext COMMENT '参文格式（NLM、APA、MLA、AMA四种）',
        `cn_ti` text COMMENT '中文的文献标题',
        `cn_ab` longtext COMMENT '中文的文献摘要',
        `cn_kw` longtext COMMENT '中文的文献关键词',
        `cn_type` text COMMENT '中文的文献的类型，综述等',
        `pt` text COMMENT '英文的文献的类型，综述等，是一个集合',
        `cn_country` text COMMENT '中文的发文的国家，区分第一或通讯以及其它的，此为非第一或通讯',
        `cn_unit` longtext COMMENT '中文的发文的机构，区分第一或通讯以及其它的，此为非第一或通讯',
        `is_cns` int(1) DEFAULT NULL COMMENT '六大顶级刊，是为1，否为0',
        `cn_fund` longtext COMMENT '中文的基金的名称',
        `cn_country_1` text COMMENT '中文的发文的国家，区分第一或通讯以及其它的，此为第一或通讯',
        `cn_unit_1` text COMMENT '中文的发文的机构，区分第一或通讯以及其它的，此为第一或通讯',
        `pmId` int(8) DEFAULT NULL COMMENT '最大8位的pmId号',
        `ut` varchar(15) DEFAULT NULL COMMENT '此为15位的UT号',
        `doi` text COMMENT 'doi号集合',
        `nlmId` varchar(25) DEFAULT NULL COMMENT 'nlmId号，无其它字符',
        `cite_score` double DEFAULT NULL COMMENT '期刊citeScore影响因子值',
        `jcr_quartile` int(1) DEFAULT NULL COMMENT 'jcr(scie)期刊分区',
        `fund` longtext COMMENT '来自wos的基金名称(FU字段)',
        `fund_list` longtext COMMENT '从原始基金信息中提供出来的基金名称，待规范。',
        `method_info` longtext COMMENT '摘要提取出来的特定字段集合',
        `trans_ok` int(1) DEFAULT NULL COMMENT '翻译完成为1，没有完成为0',
        `drug_gene_pathway_disease` longtext COMMENT '药物、基因、通路、疾病',
        `auth` longtext COMMENT '原始的作者信息，全写',
        `sort_auth` longtext COMMENT 'Chang-Ming Huang  英文名字中，新志贾这类属于正序，反之贾新志这类属于反序，程序默认为正序转反序，如果是反序则不用再转换了。',
        `info` longtext COMMENT '备用字段',
        `is_retraction` int(1) DEFAULT NULL COMMENT '是否是撤稿，是为1，否为0；',
        `is_china` int(1) DEFAULT NULL COMMENT '是否是中国人发表的，是为1，否为0；',
        `cn_discussion` longtext COMMENT '中文摘要提取出来的特定字段',
        `cn_results` longtext COMMENT '中文摘要提取出来的特定字段',
        `cn_methods` longtext COMMENT '中文摘要提取出来的特定字段',
        `cn_background` longtext COMMENT '中文摘要提取出来的特定字段',
        PRIMARY KEY (`id`),
        KEY `aid` (`aid`),
        KEY `pmId` (`pmId`),
        KEY `ut` (`ut`),
        KEY `jid` (`jid`),
        KEY `trans_ok` (`trans_ok`)
      ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
     */


}
